<?php

namespace App\Game;

class Task
{
    public $server;
    public $task_obj;
    public $redis;
    public $db;

    public function __construct($server, $task_obj, $redis, $db)
    {
        $this->server = $server;
        $this->task_obj = $task_obj;
        $this->redis = $redis;
        $this->db = $db;
    }

    public function connect()
    {
        $this->server->send($this->task_obj->fd, '请输入您的用户手机号和token');

    }

    public function auth_fail()
    {
        $this->error(401,'认证失败');
        $this->server->finish(json_encode($this->task_obj));

    }

    public function login()
    {
        //判断用户 携带的 token 和 手机 是否正确
        $user = $this->db->where('mobile', $this->task_obj->mobile)->where('token', $this->task_obj->token)->getOne('users');
        if ($user !== null) {
            //将用户信息放入 redis
            $this->redis->sAdd('member', $this->task_obj->fd);
            $this->redis->set('user_' . $this->task_obj->fd, json_encode($user));
            $this->success('登录成功');
        } else {
            $this->error(401,'认证失败');
            $this->server->finish(json_encode($this->task_obj));
        }

    }

    public function join_room()
    {
        //将用户数据放到 redis 的房间里面
        $this->redis->sAdd('room_' . $this->task_obj->room_id, $this->task_obj->fd);
        $data = $this->db->where('id', $this->task_obj->room_id)->getOne('room');
        $this->success('进入成功',$data);

    }

    public function exit_room()
    {
        //将用户数据从 redis 的房间里面清掉
        $this->redis->sRem('room_' . $this->task_obj->room_id, $this->task_obj->fd);
    }

    public function buy_prop()
    {
        $this->db->startTransaction();
        try {
            //检测积分 与 房间内 道具库存
            $room_info = $this->db->where('id', $this->task_obj->room_id)->getOne('room');
            print_r($room_info);
            //判断库存是否充足
            if ($room_info[$this->task_obj->type] < $this->task_obj->num) {
                throw new \Exception('库存不足' . '当前还剩：' . $room_info[$this->task_obj->type]);
            }

            //判断积分是否足够 假设是 100积分 一次
            $redis_user = json_decode($this->redis->get('user_' . $this->task_obj->fd));
            $user_integral = $this->db->where('user_id', $redis_user->id)->getOne('integral');
            $need_integral = $this->task_obj->num * $room_info['magnification'];
            if ($need_integral > $user_integral['usable_integral']) {
                throw new \Exception('积分不足');
            }

            //满足条件 扣积分,扣库存,增加一条积分扣除记录
            //扣积分
            $usable_integral = $user_integral['usable_integral'] - $need_integral;//扣除之后的可用积分
            $used_integral = $user_integral['used_integral'] + $need_integral;//扣除之后的可用积分
            $this->db->where('user_id', $redis_user->id)->update('integral', ['usable_integral' => $usable_integral, 'used_integral' => $used_integral, 'updated_at' => date('Y-m-d H:i:s')]);
            if ($this->db->getLastErrno() !== 0) {
                throw new \Exception('积分扣除失败');
            }

            //操作成功
            //增加一条积分扣除记录
            $insert = $this->db->insert('integral_record', [
                'user_id' => $redis_user->id,
                'integral' => $need_integral,
                'usable_integral' => $usable_integral,
                'type' => 4,
                'created_at' => date('Y-m-d H:i:s')
            ]);
            if (!$insert) {
                throw new \Exception('积分扣除记录生成失败');
            }

            //增加一条游戏记录
            $game_log = $this->db->insert('game_log', [
                'user_id' => $redis_user->id,
                'status' => 0,
                'room_id' => $this->task_obj->room_id,
                'magnification' => $room_info['magnification'],
                'prop' => $this->task_obj->type,
                'num' => $this->task_obj->num,
                'created_at' => date('Y-m-d H:i:s')
            ]);
            if (!$game_log) {
                throw new \Exception('游戏记录生成失败');
            }

            //扣库存
            $allow_num = $room_info[$this->task_obj->type] - $this->task_obj->num;//扣除之后的库存
            $this->db->where('id', $this->task_obj->room_id)->update('room', [$this->task_obj->type => $allow_num]);
            if ($this->db->getLastErrno() !== 0) {
                throw new \Exception('库存修改失败');
            }
            $this->db->commit();
            $this->success('购买成功');
            //通知用户操作成功,并发送广播给其他用户
            $members = $this->redis->sMembers('room_' . $this->task_obj->room_id);
            $room_data = $this->db->where('id', $this->task_obj->room_id)->getOne('room');
            foreach ($members as $fd) {
                $this->success('购买成功',$room_data,$fd);
            }
            $count = $this->db->where('id', $this->task_obj->room_id)
                ->where('stone', 0)
                ->where('scissors', 0)
                ->where('cloth', 0)
                ->getValue("room", "count(id)");
            if ($count == 1) {
                foreach ($members as $fd) {
                    $this->success('结算中，功能未开发',[],$fd);
                }
                //重置房间状态
                $this->db->where('id', $this->task_obj->room_id)->update('room', ['stone' => 15, 'scissors' => 15, 'cloth' => 15]);
            }


        } catch (\Exception $e) {
            $this->db->rollback();
            $this->error(400001,$e->getMessage());
        }
    }

    public function logout()
    {
        //将用户从已认证的用户列表删掉
        $this->redis->sRem('member', $this->task_obj->fd);
        $this->redis->del('user_' . $this->task_obj->fd);
    }

    private function success($msg,$data = [],$fd = ''){
        $data = [
            'code'=>200,
            'msg'=>$msg,
            'data'=>$data
        ];
        $fd = empty($fd) ? $this->task_obj->fd : $fd;
        $this->server->send($fd,json_encode($data));
    }
    private function error($code,$msg,$data = []){
        $data = [
            'code'=>$code,
            'msg'=>$msg,
            'data'=>$data
        ];
        $this->server->send($this->task_obj->fd,json_encode($data));
    }
}